//
// Created by YxMin on 2024/7/8.
//

#ifndef GAME_MAP_H
#define GAME_MAP_H
#include "Element.h"
#include "tool.h"
#include <cstdlib>
#include <cstdio>
struct Position {
    int row;
    int col;
};
struct PixelXY {
    int x,y;
};
class Map: public Element{
private:
    char matrix[15][20]{};
    constexpr const static COLORREF levelBlockColor[] = {0xffffff,0x77e558,0x57d1e5,0xcc6ee5,0xff3b8d,0x707070,0x000000};
    static COLORREF getLevelBlockColor(unsigned int level) {
        if (level > 4) {
            if (level == 9) {
                return levelBlockColor[6];
            }
            return levelBlockColor[5];
        } else {
            return levelBlockColor[level];
        }
    }
public:
    Map(int uid,int x1,int y1,int x2,int y2,int radius = 0){
        RECT r = {x1,y1,x2,y2};
        area = r;
        this->uid = uid;
        this->radius = radius;
        this->callback = callback;
    }
    bool loadFromFile(char* filename) {
        FILE* fp;
        fp = fopen(filename, "r");
        if (feof(fp))
        {
            printf("文件为空\n");
            return false;
        }
        int j=0,k=0;
        char a;
        for (int i = 0; i < 15*20; ) {
            a = fgetc(fp);
            if (a == EOF)
                return false;
            if (j == 20) {
                if (a != '\n' && a != '\r')
                    return false;
                if(a == '\r')
                    fgetc(fp);
                j = 0;
                k++;
                //printf("\n");
                continue;
            }
            matrix[k][j] = a & 0x0f;
            //printf("%c",a);
            ++i;
            j++;
        }
        fclose(fp);
        return true;
    }
    void draw() override {
        if(radius > 0) {
            roundrect(area.left,area.top,area.right,area.bottom,radius,radius);
        } else {
            rectangle(area.left,area.top,area.right,area.bottom);
        }
        //long long start = TimeMilliSecond();
        settextcolor(WHITE);
        setlinecolor(0x808080);
        for (int i = 0; i < 15; ++i) {
            for (int j = 0; j < 20; ++j) {
                setfillcolor(getLevelBlockColor(matrix[i][j]));
                int x1 = area.left + j * 40;
                int y1 = area.top + i * 40;
                fillroundrect(x1,y1,x1 + 40,y1 + 40,radius,radius);
                if (matrix[i][j] > 5 && matrix[i][j] != 9) {
                    outtextxy(x1 + 12,y1 + 3,matrix[i][j] | 0x30);
                }

            }
        }
        //printf("%lld\n",TimeMilliSecond()-start);
        setlinecolor(BLACK);
        settextcolor(BLACK);
    }
    void paintBlock(int i,int j) {
        settextcolor(WHITE);
        setlinecolor(0x808080);
        setfillcolor(getLevelBlockColor(matrix[i][j]));
        int x1 = area.left + j * 40;
        int y1 = area.top + i * 40;
        fillroundrect(x1,y1,x1 + 40,y1 + 40,radius,radius);
        if (matrix[i][j] > 5 && matrix[i][j] != 9) {
            outtextxy(x1 + 12,y1 + 3,matrix[i][j] | 0x30);
        }
        setlinecolor(BLACK);
        settextcolor(BLACK);
    }
    Position getBlockPositionByPixel(int x,int y) {
        if (x < area.left || x > area.right || y < area.top || y > area.bottom) {
            return {-1,-1};
        }
        return {(y-area.top)/40,(x-area.left)/40};
    };
    PixelXY getPixelXYByPosition(int row,int col) {
        if (row < 0 || col < 0 || row > 14 || col > 19) {
            return {-1,-1};
        }
        return {col*40 + area.left,row*40 + area.top};
    }
    char getBlockLevelByPosition(int row,int col) {
        if (row < 0 || col < 0 || row > 14 || col > 19) {
            return -1;
        }
        return matrix[row][col];
    }
    char getBlockLevelByPixel(int x,int y) {
        Position pos = getBlockPositionByPixel(x,y);
        if (x < 0)
            return -1;
        return getBlockLevelByPosition(pos.row,pos.col);
    }
    void setBlockLevelByPosition(int row,int col,char level) {
        if (row < 0 || col < 0 || row > 14 || col > 19) {
            return;
        }
        matrix[row][col] = level;
        paintBlock(row,col);
    }
    void setBlockLevelByPixel(int x,int y,char level) {
        if (x < 0)
            return;
        Position pos = getBlockPositionByPixel(x,y);
        setBlockLevelByPosition(pos.row,pos.col,level);
    }
};


#endif //GAME_MAP_H
